<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

</body>
<script>
  /* State类 */
  class State {
    buttonWasPressed() {
      throw new Error("父类的buttonWasPressed必须被重写");
    }
  }

  /* OffLightState类 */
  class OffLightState extends State {
    constructor(light) {
      super();
      this.light = light;
    };

    buttonWasPressed() {
      console.log("弱光");
      this.light.setState(this.light.weakLightState);
    }
  }

  /* WeakLightState类 */
  class WeakLightState extends State {
    constructor(light) {
      super();
      this.light = light;
    }

    buttonWasPressed() {
      console.log("强光");
      this.light.setState(this.light.strongLightState);
    }
  }

  /* StrongLight类 */
  class StrongLightState extends State {
    constructor(light) {
      super();
      this.light = light;
    }

    buttonWasPressed() {
      console.log("超强光");
      this.light.setState(this.light.superStrongLightState);
    }
  }

  /* SuperStrongLightState类 */
  class SuperStrongLightState extends State {
    constructor(light) {
      super();
      this.light = light;
    }

    buttonWasPressed() {
      console.log("关灯");
      this.light.setState(this.light.OffLightState);
    }
  }


  /* Light类 */
  class Light {
    constructor() {
      this.OffLightState = new OffLightState(this);
      this.weakLightState = new WeakLightState(this);
      this.strongLightState = new StrongLightState(this);
      this.superStrongLightState = new SuperStrongLightState(this);
      this.button = null;
    }

    init() {
      let button = document.createElement("button");
      let self = this;

      this.button = document.body.appendChild(button);
      button.innerHTML = "开关";

      this.currentState = this.OffLightState;

      this.button.onclick = function () {
        self.currentState.buttonWasPressed();
      }
    }

    setState(newState) {
      this.currentState = newState;
    }
  }

  /* 测试 */
  let light = new Light();
  light.init();
</script>

</html>